package insight.google.game.era.mgr;

import java.io.Serializable;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.appengine.api.datastore.KeyFactory;

import insight.google.game.era.bo.GameRoom;
import insight.google.game.era.bo.GameUser;
import insight.google.game.era.client.proxy.HistoryClientProxyImpl;
import insight.google.game.era.core.GameCenterManager;
import insight.google.game.era.core.Util;
import insight.google.game.era.data.GameHistory;
import insight.google.game.era.data.GameHistoryDetail;
import insight.google.game.era.data.HistoryDataManager;
import insight.google.game.era.data.Room;
import insight.google.game.era.data.RoomDataManager;
import insight.google.game.era.data.RoomHistory;
import insight.google.game.era.data.SimpleRoomDataManager;
import insight.google.game.era.data.TransactionHandler;
import insight.google.game.era.data.User;
import insight.google.game.era.data.UserDataManager;
import insight.google.game.era.data.UserGameHistory;
import insight.google.game.era.data.UserHistory;

public class HistoryManger {

	
	/**
	 * 
	 */
	private static HistoryManger instance = new HistoryManger();
	
	private static final Log log = LogFactory.getLog(HistoryManger.class);

	private HistoryManger() {

	}

	public static HistoryManger getInstance() {
		return instance;
	}

	public void getUserHistoryByUserName(String userName, String jsComponentId) {
		
		HistoryDataManager historyDataManager = null;
		try {
			historyDataManager = new HistoryDataManager(Util
					.createTranscationHandler());
			User currUser = Util.getUserBySession(historyDataManager
					.getTransactionHandler());
			UserDataManager userDataManager = new UserDataManager(historyDataManager.getTransactionHandler());
			
			User targetUser = userDataManager.findByName(userName);
			
			List<UserHistory> userHistoryList = historyDataManager
					.findUserHistoryByUserId(targetUser.getId());
			
			if(userHistoryList != null){
				List<GameHistoryDetail> userGameHistoryList = null;
				for (UserHistory userHistory : userHistoryList) {
					userGameHistoryList = historyDataManager.findUsersGameHistoryByUserHistoryId(userHistory.getId());
					if(userGameHistoryList != null){
						for (GameHistoryDetail gameHistoryDetail : userGameHistoryList) {
							userHistory.getUserGameHistoryList().add(new UserGameHistory(gameHistoryDetail));
						}
					}
				}
			}
			HistoryClientProxyImpl.getInstance().showUserHistory(
					currUser.getScriptProxy(), jsComponentId, userHistoryList);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (historyDataManager != null) {
				historyDataManager.close();
			}
		}

	}

	public void getRoomHistoryByRoomName(String roomName, String jsComponentId) {
		HistoryDataManager historyDataManager = null;
		try {
			historyDataManager = new HistoryDataManager(Util
					.createTranscationHandler());
			SimpleRoomDataManager roomDataManager = new SimpleRoomDataManager(historyDataManager.getTransactionHandler());
			User user = Util.getUserBySession(historyDataManager
					.getTransactionHandler());
			
			Room room = roomDataManager.findByName(roomName);
			List<GameHistory> gameHistoryList = historyDataManager.findAllHistoryByRoomId(room.getRoomId());
			
			if(gameHistoryList != null){
				HistoryClientProxyImpl.getInstance().showRoomHistory(user.getScriptProxy(),
						 jsComponentId, gameHistoryList);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (historyDataManager != null) {
				historyDataManager.close();
			}
		}
		// GameRoom room = Util.findRoomByName(roomName);
		// // room.loadGameHistoryByRoomName();
		// GameUser currUser = Util.getUserBySession();
		// //
		// HistoryClientProxyImpl.getInstance().showRoomHistory(currUser.getScriptProxy(),
		// jsComponentId, room.getGameHistoryList());
		// // return null;
	}

	public void creatUserHistory() {
		log.info("Creating user User History .....    ");
		HistoryDataManager historyDataManager = null;
		try {
			historyDataManager = new HistoryDataManager(Util
					.createTranscationHandler());
			User user = Util.getUserBySession(historyDataManager
					.getTransactionHandler());
			UserHistory userHistory = new UserHistory();
			userHistory.setUserId(user.getId());
			userHistory.setUserName(user.getName());
			historyDataManager.addToDataStore(userHistory);

			UserDataManager userDataManager = new UserDataManager(
					historyDataManager.getTransactionHandler());
			user.setCurrentUserHistoryId(userHistory.getId());
			userDataManager.addToDataStore(user);
			historyDataManager.commit();
			log.info("User history has been created .........");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (historyDataManager != null) {
				historyDataManager.close();
			}
			log.info("User history creation finished");
		}

	}

	public void updateUserHistory4GameCount(GameRoom room) {

		HistoryDataManager historyDataManager = null;
		try {
			historyDataManager = new HistoryDataManager(Util
					.createTranscationHandler());
			UserHistory userHistory = null;
			for (GameUser gameUser : room.getUserList()) {
//				userHistory = historyDataManager.findUserHistoryById(gameUser.getCurrentUserHistoryId());
//				userHistory
//						.setNoOfGamePlayed(userHistory.getNoOfGamePlayed() + 1);
//				historyDataManager.addToDataStore(userHistory);

			}

			
			historyDataManager.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (historyDataManager != null) {
				historyDataManager.close();
			}
		}

	}

	public void createGameHistory(GameRoom gameRoom) {
		HistoryDataManager historyDataManager = null;
		try {
			historyDataManager = new HistoryDataManager(Util
					.createTranscationHandler());
			SimpleRoomDataManager roomDataManager = new SimpleRoomDataManager(
					historyDataManager.getTransactionHandler());
			Room room = roomDataManager.findByName(gameRoom.getRoomName());
			GameHistory gameHistory = this.initGameHistory(gameRoom,
					historyDataManager.getTransactionHandler());
			historyDataManager.addToDataStore(gameHistory);
			room.setCurrentGameHistoryId(gameHistory.getId());
			roomDataManager.addToDataStore(room);
			historyDataManager.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (historyDataManager != null) {
				historyDataManager.close();
			}
		}
		this.updateUserHistory4GameCount(gameRoom);
	}

	public void updateGameHistory4Characters(GameRoom gameRoom) {
		HistoryDataManager historyDataManager = null;
		try {
			historyDataManager = new HistoryDataManager(Util
					.createTranscationHandler());
			SimpleRoomDataManager roomDataManager = new SimpleRoomDataManager(
					historyDataManager.getTransactionHandler());
			Room room = roomDataManager.findByName(gameRoom.getRoomName());
			GameHistory gameHistory = historyDataManager.findGameHistoryById(room.getCurrentGameHistoryId());
			
			List<GameUser> userList = gameRoom.getUserList();
			List<GameHistoryDetail> gameHistoryDetailList = gameHistory.getGameHistoryDetailList();
			User user = null;
			GameHistoryDetail gameHistoryDetail = null;
			for (GameUser gameUser : userList) {
				for (int i = 0; i < gameHistoryDetailList.size(); i++) {
					gameHistoryDetail = gameHistoryDetailList.get(i);
//					if(gameHistoryDetail.getUserHistoryId().equals(gameUser.getCurrentUserHistoryId())){
//						gameHistoryDetail.setCharacterName(gameUser.getCharacterCard().getName());
//						break;
//					}
				}
			}
			
			historyDataManager.addToDataStore(gameHistory);
			room.setCurrentGameHistoryId(gameHistory.getId());
			roomDataManager.addToDataStore(room);
			historyDataManager.commit();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (historyDataManager != null) {
				historyDataManager.close();
			}
		}
	}
	
	
	public void gameOver(String currRoomName) {
		HistoryDataManager historyDataManager = null;
		SimpleRoomDataManager roomDataManager = null;
		RoomDataManager gameRoomDataManager =null;
		UserDataManager userDataManager = null;
		GameRoom gameRoom = null;
		User user = Util.getUserBySession();
		
		try {
			historyDataManager = new HistoryDataManager(Util.createTranscationHandler());
			
//			user = Util.getUserBySession(historyDataManager.getTransactionHandler());
			
			roomDataManager = new SimpleRoomDataManager(historyDataManager.getTransactionHandler());
			
			gameRoomDataManager =new RoomDataManager(historyDataManager.getTransactionHandler());
			
			
			
			gameRoom = gameRoomDataManager.findByName(currRoomName);
			
			if(gameRoom !=null 
					&& gameRoom.getGameState() == insight.google.game.era.bo.Room.GAME_OVER){
				
				Room room = roomDataManager.findByName(gameRoom.getRoomName());
				
				GameHistory gameHistory = historyDataManager.findGameHistoryById(room.getCurrentGameHistoryId());
				
				List<GameUser> gameUserList = gameRoom.getUserList();
				List<GameHistoryDetail> gameHistoryDetailList = gameHistory.getGameHistoryDetailList();
//				User user = null;
				GameHistoryDetail gameHistoryDetail = null;
				for (GameUser gameUser : gameUserList) {
					for (int i = 0; i < gameHistoryDetailList.size(); i++) {
						gameHistoryDetail = gameHistoryDetailList.get(i);
//						if(gameHistoryDetail.getUserHistoryId().equals(gameUser.getCurrentUserHistoryId())){
//							gameHistoryDetail.setGameResultStatus(gameUser.getState());
//							
//							break;
//						}
					}
				}
				gameHistory.setEndTime(new Date());
				historyDataManager.addToDataStore(gameHistory);
				historyDataManager.commit();
				
				userDataManager = new UserDataManager(Util.createTranscationHandler());
				List<User> userList =  userDataManager.findAllByRoomId(gameRoom.getRoomId());
				if(userList != null){
					for (User roomUser : userList) {
						roomUser.reset();
						userDataManager.addToDataStore(roomUser);
					}
				}
				userDataManager.commit();
				
				gameRoomDataManager =new RoomDataManager(Util.createTranscationHandler(),true);
				gameRoom = gameRoomDataManager.findByName(currRoomName);
				gameRoomDataManager.removeFromDataStore(gameRoom);
//				log.debug("Deleted  ...   "+ gameRoom.getRoomName());
				gameRoomDataManager.commit();
				
				gameRoomDataManager =new RoomDataManager(Util.createTranscationHandler());
				gameRoomDataManager.addToDataStore(new GameRoom(currRoomName));
				gameRoomDataManager.commit();
				
				roomDataManager = new SimpleRoomDataManager(Util.createTranscationHandler());
				room = roomDataManager.findByName(currRoomName);
				room.reset();
				roomDataManager.addToDataStore(room);
				
				roomDataManager.commit();
				log.info(room.getName() + " .. Room has been reset .... "+ room.getPlayerCount());
				
				
				
				
				
//				
			}else{
				userDataManager = new UserDataManager(Util.createTranscationHandler());
				user = Util.getUserBySession(Util.createTranscationHandler());
				user.reset();
				userDataManager.addToDataStore(user);
				userDataManager.commit();
				
			}
		
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (historyDataManager != null) {
				historyDataManager.close();
			}
			if (userDataManager != null) {
				userDataManager.close();
			}
			if (gameRoomDataManager != null) {
				gameRoomDataManager.close();
			}
			if (roomDataManager != null) {
				roomDataManager.close();
			}
		}
	}

	private GameHistory initGameHistory(GameRoom room,
			TransactionHandler txHandler) {
		GameHistory gameHistory = new GameHistory();
		GameHistoryDetail gameHistoryDetail = null;
		
		UserDataManager userDataManager = new UserDataManager(txHandler);
		SimpleRoomDataManager simpleRoomDataManager = new SimpleRoomDataManager(txHandler);
		List<GameUser> userList = room.getUserList();
		User user = null;
		GameHistoryDetail gameHisrtotyDetail = null;
		for (GameUser gameUser : userList) {
			user = userDataManager.findByName(gameUser.getName());
			if (user.getName().equals(room.getOwnerName())) {
				gameHistory.setOwnerId(KeyFactory.keyToString(gameUser.getId()));

			}
			gameHisrtotyDetail = this.creatGameHistoryDetail(gameUser);
			gameHisrtotyDetail.setUserId(user.getId());
			gameHistory.getGameHistoryDetailList().add(gameHisrtotyDetail);
			
		}
		gameHistory.setRoomName(room.getRoomName());
		gameHistory.setRoomId(KeyFactory.keyToString(simpleRoomDataManager.findByName(room.getRoomName()).getRoomId()));
		gameHistory.setNoOfUsers(userList.size());
		gameHistory.setStartTime(new Date());
		gameHistory.setStatus(room.getGameState());

		return gameHistory;

	}

	private GameHistoryDetail creatGameHistoryDetail(GameUser user) {
		GameHistoryDetail gameHistoryDetail = new GameHistoryDetail();
		gameHistoryDetail.setUserName(user.getName());
		if (user.getRoleCard() != null) {
			gameHistoryDetail.setRoleName(user.getRoleCard().getName());
		}
//		if (user.getCurrentUserHistoryId() != null) {
//			gameHistoryDetail.setUserHistoryId(user.getCurrentUserHistoryId());
//		}
		return gameHistoryDetail;

	}

}
